package com.macro.mall.portal.controller.oms;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.Page;
import com.macro.mall.common.api.CommonPage;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.common.api.exception.BusinessException;
import com.macro.mall.model.UmsMember;
import com.macro.mall.oms.domain.Order;
import com.macro.mall.oms.entity.OrderEntity;
import com.macro.mall.oms.entity.OrderItemEntity;
import com.macro.mall.oms.service.order.OrderItemService;
import com.macro.mall.oms.service.order.OrderService;
import com.macro.mall.oms.service.order.bo.CreateOrderInput;
import com.macro.mall.oms.service.order.bo.PagedQueryOrderInput;
import com.macro.mall.oms.service.order.bo.UpdateOrderInput;
import com.macro.mall.portal.controller.BaseController;
import com.macro.mall.portal.domain.FrontOrder;
import com.macro.mall.portal.dto.oms.CreateOrderReqDto;
import com.macro.mall.portal.dto.oms.PagedQueryOrderReqDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 订单控制器
 *
 * @author xuyanjun
 * @date 2019-12-15
 */
@Api(tags = "OrderController", description = "订单")
@Slf4j(topic = "OrderController")
@RestController
@RequestMapping("/order")
public class OrderController extends BaseController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderItemService orderItemService;

    /**
     * 创建订单
     *
     * @return 订单id
     */
    @PreAuthorize("isAuthenticated()")
    @ApiOperation("创建订单")
    @PostMapping("create")
    public CommonResult<Long> create(@RequestBody CreateOrderReqDto reqDto) {
        UmsMember currentUser = getCurrentUser();

        CreateOrderInput createOrderInput = new CreateOrderInput();
        createOrderInput.setMemberId(currentUser.getId())
                .setAddressId(reqDto.getAddressId())
                .setQty(reqDto.getQty())
                .setSkuId(reqDto.getSkuId())
                .setRemark(reqDto.getRemark());

        long orderId = orderService.create(createOrderInput);

        return CommonResult.success(orderId);
    }

    /**
     * 分页查询订单
     *
     * @return 分页后的订单
     */
    @PreAuthorize("isAuthenticated()")
    @ApiOperation("分页查询订单")
    @PostMapping("pagedQuery")
    public CommonPage<FrontOrder> pagedQuery(@RequestBody PagedQueryOrderReqDto reqDto) {
        UmsMember currentUser = getCurrentUser();

        PagedQueryOrderInput pagedQueryOrderInput = new PagedQueryOrderInput();
        pagedQueryOrderInput
                .setMemberId(currentUser.getId())
                .setStatus(reqDto.getStatus())
                .setPageIndex(reqDto.getPageIndex())
                .setPageSize(reqDto.getPageSize())
                .setSortField("create_time")
                .setSortDirection("desc");

        Page<OrderEntity> page = orderService.pagedQuery(pagedQueryOrderInput);

        List<Order> orders = orderService.entityToDomain(page);
        List<FrontOrder> frontOrders = orderToFront(orders);

        return CommonPage.restPage(frontOrders, page);
    }

    private List<FrontOrder> orderToFront(List<Order> orders) {
        List<Long> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());
        List<OrderItemEntity> orderItemEntities = orderItemService.listByBatchOrderIds(orderIds);

        List<FrontOrder> result = new ArrayList<>();
        for (Order order : orders) {
            FrontOrder frontOrder = new FrontOrder();
            BeanUtil.copyProperties(order, frontOrder);

            OrderItemEntity orderItemEntity = orderItemEntities.stream().filter(x -> x.getOrderId().equals(order.getId())).findFirst().get();
            frontOrder.setProductName(orderItemEntity.getProductName())
                    .setProductPic(orderItemEntity.getProductPic())
                    .setSpec(Arrays.asList(orderItemEntity.getSp1()))
                    .setUnitPrice(orderItemEntity.getProductPrice())
                    .setQty(orderItemEntity.getProductQuantity() == null ? 1 : orderItemEntity.getProductQuantity());

            result.add(frontOrder);
        }

        return result;
    }

    /**
     * 根据id获取订单
     *
     * @param id id
     * @return 订单
     */
    @ApiOperation("根据id获取订单")
    @GetMapping("{id}")
    public CommonResult<FrontOrder> getById(@PathVariable long id) {
        if (id <= 0) {
            throw new BusinessException("要获取的订单Id不能为空。");
        }

        OrderEntity orderEntity = orderService.getById(id);
        if (orderEntity == null) {
            throw new BusinessException(String.format("要获取的订单id:%s不存在。", id));
        }

        Order order = orderService.entityToDomain(orderEntity);

        List<Order> orders = new ArrayList<>();
        orders.add(order);
        List<FrontOrder> frontOrders = orderToFront(orders);

        return CommonResult.success(frontOrders.get(0));
    }

    /**
     * 根据批量id获取订单
     *
     * @param ids ids
     * @return 订单
     */
    @ApiOperation("根据批量id获取订单")
    @PostMapping("listByBatchIds")
    public CommonResult<List<Order>> listByBatchIds(@RequestBody List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("要获取的订单Id集合不能为空。");
        }

        List<OrderEntity> orderEntities = orderService.listByBatchIds(ids);

        List<Order> orders = orderService.entityToDomain(orderEntities);
        return CommonResult.success(orders);
    }

    /**
     * 订单确认收货
     *
     * @param orderId orderId
     * @return 订单
     */
    @PreAuthorize("isAuthenticated()")
    @ApiOperation("订单确认收货")
    @PostMapping("receive")
    public CommonResult listByBatchIds(@ApiParam("订单id") @RequestParam("orderId") Long orderId) {
        UmsMember currentUser = getCurrentUser();
        OrderEntity orderEntity = orderService.getById(orderId);

        Assert.isTrue(currentUser.getId().equals(orderEntity.getMemberId()), "此订单不属于您。");
        Assert.isTrue(orderEntity.getStatus() == 1 || orderEntity.getStatus() == 2
                , "只有处于【待发货】或【待收货】的订单才能确认收货。");


        UpdateOrderInput updateOrderEntity = new UpdateOrderInput();
        updateOrderEntity
                .setId(orderEntity.getId())
                .setStatus(3)
                .setReceiveTime(LocalDateTime.now())
                .setSettleStatus(5)
                .setSettlePrice(orderEntity.getCommission());

        orderService.update(updateOrderEntity);

        return CommonResult.success(null);
    }

}

